package ucron

import (
    "sync"
    "reflect"
    "github.com/jakecoffman/cron"
)

// @Description: job info的对象操作相关，外部需要使用
type JobModel struct {
    Pkg             string
    Name            string
    FullName        string

    Job             cron.Job
    JobName         string
}

/**
 @Description：创建一个新的job
 @Param:
 @Return：
 */
func newJobInfo(val reflect.Value) *JobModel {
    j := &JobModel{}

    indr := reflect.Indirect(val)
    j.Pkg = indr.Type().PkgPath()
    j.Name = indr.Type().Name()
    j.FullName = getFullName(indr.Type())

    return j
}

var (
    jobCache = &_jobCache{
        cache:              make(map[string]*JobModel),
        cacheByFullName:    make(map[string]*JobModel),
    }
)

// @Description: cache容器处理
type _jobCache struct {
    sync.RWMutex
    orders              []string
    cache               map[string]*JobModel
    cacheByFullName     map[string]*JobModel
    done                bool
}

/**
 @Description：获取所有的任务名
 @Param:
 @Return：
 */
func (j *_jobCache) allJobName() []string {
    return j.orders
}

/**
 @Description：all所有的job
 @Param:
 @Return：
 */
func (j *_jobCache) all() map[string]*JobModel {
    jis := make(map[string]*JobModel, len(j.cache))
    for k, v := range j.cache {
        jis[k] = v
    }
    return jis
}

/**
@Description：allOrder，order过的job
@Param:
@Return：
*/
func (j *_jobCache) allOrder() []*JobModel {
    jis := make([]*JobModel, 0, len(j.orders))
    for _, name := range j.orders {
        jis = append(jis, j.cache[name])
    }
    return jis
}

/**
 @Description：get by name
 @Param:
 @Return：
 */
func (j *_jobCache) get(name string) (ji *JobModel, exist bool) {
    ji, exist = j.cache[name]
    return
}

/**
 @Description：get by full name
 @Param:
 @Return：
 */
func (j *_jobCache) getByFullName(fullName string) (ji *JobModel, exist bool) {
    ji, exist = j.cacheByFullName[fullName]
    return
}

/**
 @Description：设置一个job，设置新的返回旧的
 @Param:
 @Return：
 */
func (j *_jobCache) set(job string, ji *JobModel) *JobModel {
    jii := j.cache[job]
    j.cache[job] = ji
    j.cacheByFullName[ji.FullName] = ji
    if jii == nil {
        j.orders = append(j.orders, job)
    }
    return jii
}

/**
 @Description：清楚cache中的资源
 @Param:
 @Return：
 */
func (j *_jobCache) clean()  {
    j.orders = make([]string, 0)
    j.cache = make(map[string]*JobModel)
    j.cacheByFullName = make(map[string]*JobModel)
    j.done = false
}

/**
 @Description：清楚cache中的资源
 @Param:
 @Return：
 */
func ResetJobCache()  {
    jobCache.clean()
}